package com.sanshi.project.assets.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sanshi.project.admin.api.entity.CodeRecordEntity;
import com.sanshi.project.admin.api.entity.CodeRuleEntity;
import com.sanshi.project.admin.api.entity.CodeRuleItemEntity;
import com.sanshi.project.assets.mapper.CodeRecordMapper;
import com.sanshi.project.assets.mapper.CodeRuleItemMapper;
import com.sanshi.project.assets.mapper.CodeRuleMapper;
import com.sanshi.project.assets.service.CodeRuleService;
import com.sanshi.project.common.core.util.R;
import dm.jdbc.util.StringUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Random;

/**
 * 编码规则配置表
 *
 * @author nikon
 * @date 2023-11-10 19:51:11
 */
@Service
@RequiredArgsConstructor
public class CodeRuleServiceImpl extends ServiceImpl<CodeRuleMapper, CodeRuleEntity> implements CodeRuleService {
    private final CodeRuleItemMapper codeRuleItemMapper;
    private final CodeRecordMapper codeRecordMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveDeep(CodeRuleEntity codeRule) {
        baseMapper.insert(codeRule);
        for (CodeRuleItemEntity codeRuleItem : codeRule.getCodeRuleItemList()) {
            codeRuleItem.setCodeRuleId(codeRule.getId());
            codeRuleItemMapper.insert(codeRuleItem);
        }

        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateDeep(CodeRuleEntity codeRule) {
        baseMapper.updateById(codeRule);
        for (CodeRuleItemEntity codeRuleItem : codeRule.getCodeRuleItemList()) {
            if (Objects.isNull(codeRuleItem.getId())) {
                codeRuleItem.setCodeRuleId(codeRule.getId());
                codeRuleItemMapper.insert(codeRuleItem);
            } else {
                codeRuleItemMapper.updateById(codeRuleItem);
            }
        }
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeDeep(Long[] ids) {
        baseMapper.deleteBatchIds(CollUtil.toList(ids));
        codeRuleItemMapper.delete(Wrappers.<CodeRuleItemEntity>lambdaQuery().in(CodeRuleItemEntity::getCodeRuleId, ids));
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeChild(Long[] ids) {
        codeRuleItemMapper.deleteBatchIds(CollUtil.toList(ids));
        return Boolean.TRUE;
    }

    @Override
    public R<String> generateCode(CodeRuleEntity codeRule) {
        if (!StrUtil.isNotEmpty(codeRule.getType())) {
            return R.failed("生成编码时，必须传入业务类型！");
        }
        String code = "";
        // 流水号
        int currentMaxCode = 0;
        LambdaQueryWrapper<CodeRuleEntity> wrapper = Wrappers.lambdaQuery();
        // 默认查询：状态【启用中】，限制一条
        wrapper.eq(CodeRuleEntity::getStatus, "1").last("limit 1");
        // 业务类型
        wrapper.eq(CodeRuleEntity::getType, codeRule.getType());
        CodeRuleEntity myCodeRule = baseMapper.selectOne(wrapper);
        if (myCodeRule == null) {
            return R.failed(String.format("使用编码规则前，请先配置对应业务类型（%s）的编码规则！", codeRule.getType()));
        }
        // 获取子编码列表
        LambdaQueryWrapper<CodeRuleItemEntity> codeRuleItemWrapper = Wrappers.lambdaQuery();
        codeRuleItemWrapper.eq(CodeRuleItemEntity::getCodeRuleId, myCodeRule.getId()).orderByAsc(CodeRuleItemEntity::getSort);
        List<CodeRuleItemEntity> codeRuleItemEntityList = codeRuleItemMapper.selectList(codeRuleItemWrapper);
        for (CodeRuleItemEntity codeRuleItem : codeRuleItemEntityList) {
            // type: 1（（字符串）、2（连接符）、3（日期时间）、4（流水号）、5（随机数）
            switch (codeRuleItem.getType()) {
                // 字符串
                case "1": {
                    code = code.concat(codeRuleItem.getValue());
                }
                ;
                break;
                // 连接符
                case "2": {
                    code = code.concat(codeRuleItem.getValue());
                }
                ;
                break;
                // 日期时间
                case "3": {
                    // java只支持yyyy-MM-dd HH:mm:ss
                    // 创建一个Date对象
                    Date date = new Date();
                    // 创建一个SimpleDateFormat对象，指定日期格式
                    SimpleDateFormat sdf = new SimpleDateFormat(codeRuleItem.getValue());
                    // 使用SimpleDateFormat的format方法将日期对象格式化为指定格式的字符串
                    String formattedDate = sdf.format(date);
                    code = code.concat(formattedDate);
                }
                ;
                break;
                // 流水号
                case "4": {
                    LambdaQueryWrapper<CodeRecordEntity> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(CodeRecordEntity::getType, myCodeRule.getType()) //填入查询条件
                            .select(CodeRecordEntity::getSortNo) // 填入需要查询的字段
                            .orderByDesc(CodeRecordEntity::getSortNo) // 按该字段降序排序
                            .last("LIMIT 1"); // 只返回最大值的一条记录
                    CodeRecordEntity maxEntity = codeRecordMapper.selectOne(queryWrapper);
                    String codeStr = StringUtil.EMPTY;
                    if (maxEntity != null) {
                        currentMaxCode = maxEntity.getSortNo() + 1;
                        codeStr = StringUtils.leftPad(StringUtil.toString(currentMaxCode), Integer.parseInt(codeRuleItem.getValue()), "0");
                    } else {
                        codeStr = StringUtils.leftPad("1", Integer.parseInt(codeRuleItem.getValue()), "0");
                    }
                    code = code.concat(codeStr);
                }
                ;
                break;
                // 随机数
                case "5": {
                    String maxNum = StringUtils.leftPad("9", Integer.parseInt(codeRuleItem.getValue()), "9");
                    // 随机生成1到maxNum+1之间的整数
                    Random random = new Random();
                    String randomInt = StrUtil.toString(random.nextInt(Integer.parseInt(maxNum)) + 1);
                    String codeStr = StringUtils.leftPad(randomInt, Integer.parseInt(codeRuleItem.getValue()), "0");
                    code = code.concat(codeStr);
                }
                ;
                break;
            }
        }
        // 记录编码，0否，1是
        if (myCodeRule.getIsRecord().equals("1")) {
            CodeRecordEntity codeRecord = new CodeRecordEntity();
            codeRecord.setType(myCodeRule.getType());
            codeRecord.setName(myCodeRule.getName());
            codeRecord.setValue(code);
            if (currentMaxCode > 0) {
                codeRecord.setSortNo(currentMaxCode);
            }
            codeRecordMapper.insert(codeRecord);
        }
        return R.ok(code);
    }
}